﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DTO;
using BUS;
using System.Drawing.Drawing2D;
using System.IO;
using System.Globalization;


namespace DataTool
{
    public struct ControlState
    {
        public int ColumnIndexModule;
        public int RowIndexModule;
        public int ColumnIndexFrame;
        public int RowIndexFrame;
        public int ColumnIndexFModule;
        public int RowIndexFModule;
        public int ColumnIndexAnimation;
        public int RowIndexAnimation;
        public int ColumnIndexAFrame;
        public int RowIndexAFrame;
    };
    public partial class frmMain : Form
    {
        SpriteDTO m_sprite;
        bool m_wasSpriteChange;
        OptionDTO m_option;

        public frmMain()
        {
            InitializeComponent();
            m_option = new OptionDTO();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            m_HistorySprites = new SpriteDTO[MAX_SPTIRE_STORE];
            m_HistoryControlState = new ControlState[MAX_SPTIRE_STORE];
            for (int i = 0; i < MAX_SPTIRE_STORE; i++)
            {
                m_HistorySprites[i] = new SpriteDTO();
                m_HistoryControlState[i] = new ControlState();
            }
            m_sprite = new SpriteDTO();// SpriteBUS.Load("sprite.xml");
            ReFreshSpriteStore();
            m_wasSpriteChange = false;
            //txtImage.Text = m_sprite.ImageInfo[0].Path;



            m_ImageViewerPosX = pnlImageViewer.Width / 2;
            m_ImageViewerPosY = pnlImageViewer.Height / 2;
            m_ScaleImageViewer = 1;
            m_penAqua = new Pen(Color.Aqua, 1);
            m_penLinearRed = new Pen(Color.Red, 1);

            m_penLinearRed.DashStyle = DashStyle.DashDot;

            m_brGradient = new LinearGradientBrush(new Rectangle(0, 0, pnlImageViewer.Width, pnlImageViewer.Height - hsbImageModuleList.Height), Color.White, Color.Violet, 45, false);

            InitHScrool();
            //pnlTransColor.BackColor = Color.FromArgb(m_sprite.ImageInfo[0].Transp);

            pnlTransColor.Invalidate();

            openFileSprite.Filter = "XML Sprite Files (*.XML)|*.xml|" +
                "All files (*.*)|*.*";
            saveFileSprite.Filter = "XML Sprite Files (*.XML)|*.xml|" +
                "All files (*.*)|*.*";
        }

        #region Modules
        int m_RowIndexModule;
        int m_ColumnIndexModule;
        private void StoreSelectModule()
        {
            if (grvModule.SelectedCells.Count == 0)
            {
                m_RowIndexModule = -1;
                m_ColumnIndexModule = -1;
            }
            else
            {
                m_RowIndexModule = grvModule.SelectedCells[0].RowIndex;
                m_ColumnIndexModule = grvModule.SelectedCells[0].ColumnIndex;
            }
        }
        private void ReStoreSelectModule()
        {
            if (m_RowIndexModule >= grvModule.Rows.Count)
                m_RowIndexModule = grvModule.Rows.Count - 1;
            if (m_RowIndexModule < 0 || m_ColumnIndexModule < 0)
                return;
            grvModule.CurrentCell = grvModule[m_ColumnIndexModule, m_RowIndexModule];
        }
        private void grvModule_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            m_IsDrawBoundRect = true;
            m_NeedTestMouseWithRect = true;
            m_RowIndexModule = e.RowIndex;
            m_ColumnIndexModule = e.ColumnIndex;
            pnlImageViewer.Invalidate();
        }
        private void grvModule_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            int index = e.RowIndex;
            //SpriteBUS.SetEditModule(index);
            SpriteBUS.SaveRowModule(m_sprite, index);
            SpriteStore();
        }
        private void btnModule_NewRow_Click(object sender, EventArgs e)
        {
            SpriteBUS.NewRowModule(m_sprite);
            grvModule.CurrentCell = grvModule[3, grvModule.Rows.Count - 1];
        }
        private void btnModule_SaveRow_Click(object sender, EventArgs e)
        {
            StoreSelectModule();
            SpriteBUS.SaveRowModule(m_sprite, m_RowIndexModule);
            //ReStoreSelectModule();
        }
        private void btnModuleSaveAll_Click(object sender, EventArgs e)
        {
            //StoreSelectModule();
            SpriteBUS.SaveAllModule(m_sprite);
            //ReStoreSelectModule();
        }
        private void btnModuleDelRow_Click(object sender, EventArgs e)
        {
            StoreSelectModule();
            SpriteBUS.DelRowModule(m_sprite, m_RowIndexModule);
            //StoreSelectModule();
            pnlImageViewer.Invalidate();
            //ReStoreSelectModule();
        }
        private void btnMudule_Clone_Click(object sender, EventArgs e)
        {
            StoreSelectModule();
            if (SpriteBUS.CloneRowModule(m_sprite, m_RowIndexModule))
            {
                grvModule.CurrentCell = grvModule[3, grvModule.Rows.Count - 1];
            }
        }

        private void btnModule_Up_Click(object sender, EventArgs e)
        {
            StoreSelectModule();
            int newCol = m_ColumnIndexModule;
            int newRow = m_RowIndexModule - 1;
            if (SpriteBUS.ModuleRowUp(m_sprite, m_RowIndexModule))
                grvModule.CurrentCell = grvModule[newCol, newRow];
        }

        private void btnModule_Down_Click(object sender, EventArgs e)
        {
            StoreSelectModule();
            int newCol = m_ColumnIndexModule;
            int newRow = m_RowIndexModule + 1;
            if (SpriteBUS.ModuleRowDown(m_sprite, m_RowIndexModule))
                grvModule.CurrentCell = grvModule[newCol, newRow];
        }

        private void btnModuleChangeImage_Click(object sender, EventArgs e)
        {
            string path = txtImage.Text;
            Bitmap image = null;
            try
            {
                if (string.IsNullOrEmpty(m_sprite.FilePath))
                {
                    string absDir = Path.Combine(Directory.GetCurrentDirectory(), path);
                    image = new Bitmap(absDir);
                }
                else
                {
                    string absDir = Path.Combine(Path.GetDirectoryName(m_sprite.FilePath), path);
                    image = new Bitmap(absDir);
                }
            }
            catch
            {

            }
            if (m_sprite.ImageInfo.Count == 0)
                m_sprite.ImageInfo.Add(new ImageInfo());
            m_sprite.ImageInfo[0].Image = image;
            m_sprite.ImageInfo[0].Path = path;
            pnlImageViewer.Invalidate();
            pnlImageMuduleList.Invalidate();
        }
        private void pnlTransColor_MouseUp(object sender, MouseEventArgs e)
        {
            colorChosen.Color = pnlTransColor.BackColor;
            if (colorChosen.ShowDialog() == DialogResult.OK)
            {
                pnlTransColor.BackColor = colorChosen.Color;
                m_sprite.ImageInfo[0].Transp = pnlTransColor.BackColor.ToArgb();
                m_sprite.ImageInfo[0].ImageAttr.SetColorKey(pnlTransColor.BackColor, pnlTransColor.BackColor);
                pnlImageViewer.Invalidate();
                pnlImageMuduleList.Invalidate();
            }
        }
        #endregion

        #region Frame
        int m_RowIndexFrame;
        int m_ColumnIndexFrame;
        private void StoreSelectFrame()
        {
            if (dgvFrames.SelectedCells.Count == 0)
            {
                m_RowIndexFrame = -1;
                m_ColumnIndexFrame = -1;
            }
            else
            {
                m_RowIndexFrame = dgvFrames.SelectedCells[0].RowIndex;
                m_ColumnIndexFrame = dgvFrames.SelectedCells[0].ColumnIndex;
            }
        }
        private void ReStoreSelectFrame()
        {
            if (m_RowIndexFrame >= dgvFrames.Rows.Count)
                m_RowIndexFrame = dgvFrames.Rows.Count - 1;
            if (m_RowIndexFrame < 0 || m_ColumnIndexFrame < 0)
                return;
            dgvFrames.CurrentCell = dgvFrames[m_ColumnIndexFrame, m_RowIndexFrame];
        }
        private void dgvFrames_SelectionChanged(object sender, EventArgs e)
        {
            m_IsDrawBoundRect = false;
            StoreSelectFrame();
            dgvFModules.DataSource = SpriteBUS.GetDataFModule(m_sprite, m_RowIndexFrame);

            //StoreSelectFrame();
            pnlImageViewer.Invalidate();
        }
        private void dgvFrames_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            m_IsDrawBoundRect = false;
            m_RowIndexFrame = e.RowIndex;
            m_ColumnIndexFrame = e.ColumnIndex;
            dgvFModules.DataSource = SpriteBUS.GetDataFModule(m_sprite, m_RowIndexFrame);
        }
        private void dgvFrames_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            int index = e.RowIndex;
            //SpriteBUS.SetEditFrame(index);
            SpriteBUS.SaveRowFrame(m_sprite, index);
            pnlImageViewer.Invalidate();
        }
        private void btnFrame_NewRow_Click(object sender, EventArgs e)
        {
            SpriteBUS.NewRowFrame(m_sprite);
            dgvFrames.CurrentCell = dgvFrames[3, dgvFrames.Rows.Count - 1];
            dgvFModules.DataSource = SpriteBUS.GetDataFModule(m_sprite, dgvFrames.Rows.Count - 1);
        }
        private void btnFrame_Clone_Click(object sender, EventArgs e)
        {
            StoreSelectFrame();
            if (SpriteBUS.CloneRowFrame(m_sprite, m_RowIndexFrame))
            {
                dgvFrames.CurrentCell = dgvFrames[3, dgvFrames.Rows.Count - 1];
                dgvFModules.DataSource = SpriteBUS.GetDataFModule(m_sprite, dgvFrames.Rows.Count - 1);
            }
        }
        private void btnFrame_SaveRow_Click(object sender, EventArgs e)
        {
            StoreSelectFrame();
            SpriteBUS.SaveRowFrame(m_sprite, m_RowIndexFrame);
        }
        private void btnFrame_SaveAll_Click(object sender, EventArgs e)
        {
            SpriteBUS.SaveAllFrame(m_sprite);
        }
        private void btnFrame_DelRow_Click(object sender, EventArgs e)
        {
            StoreSelectFrame();
            SpriteBUS.DelRowFrame(m_sprite, m_RowIndexFrame);
        }


        private void btnFrame_Up_Click(object sender, EventArgs e)
        {
            StoreSelectFrame();
            int newCol = m_ColumnIndexFrame;
            int newRow = m_RowIndexFrame - 1;
            if (SpriteBUS.FrameRowUp(m_sprite, m_RowIndexFrame))
                dgvFrames.CurrentCell = dgvFrames[newCol, newRow];
        }

        private void btnFrame_Down_Click(object sender, EventArgs e)
        {
            StoreSelectFrame();
            int newCol = m_ColumnIndexFrame;
            int newRow = m_RowIndexFrame + 1;
            if (SpriteBUS.FrameRowDown(m_sprite, m_RowIndexFrame))
                dgvFrames.CurrentCell = dgvFrames[newCol, newRow];
        }
        #endregion

        #region FModule
        int m_RowIndexFModule;
        int m_ColumnIndexFModule;
        private void StoreSelectFModule()
        {
            if (dgvFModules.SelectedCells.Count == 0)
            {
                m_RowIndexFModule = -1;
                m_ColumnIndexFModule = -1;
            }
            else
            {
                m_RowIndexFModule = dgvFModules.SelectedCells[0].RowIndex;
                m_ColumnIndexFModule = dgvFModules.SelectedCells[0].ColumnIndex;
            }
        }
        private void ReStoreSelectFModule()
        {
            if (m_RowIndexFModule >= dgvFModules.Rows.Count)
                m_RowIndexFModule = dgvFModules.Rows.Count - 1;
            if (m_RowIndexFModule < 0 || m_ColumnIndexFModule < 0)
                return;
            dgvFModules.CurrentCell = dgvFModules[m_ColumnIndexFModule, m_RowIndexFModule];
        }
        private void dgvFModules_SelectionChanged(object sender, EventArgs e)
        {
            StoreSelectFModule();
            pnlImageViewer.Invalidate();
        }
        private void dgvFModules_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            m_IsDrawBoundRect = true;
            m_NeedTestMouseWithRect = true;
            m_RowIndexFModule = e.RowIndex;
            m_ColumnIndexFModule = e.ColumnIndex;
            pnlImageViewer.Invalidate();
        }
        private void dgvFModules_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            int index = e.RowIndex;
            //SpriteBUS.SetEditFModule(index);
            SpriteBUS.SaveRowFModule(m_sprite, m_RowIndexFrame, index);
            pnlImageViewer.Invalidate();
        }
        private void btnFModule_NewRow_Click(object sender, EventArgs e)
        {
            if (SpriteBUS.NewRowFModule(m_sprite, m_RowIndexFrame))
                dgvFModules.CurrentCell = dgvFModules[3, dgvFModules.Rows.Count - 1];
        }
        private void btnFModule_Clone_Click(object sender, EventArgs e)
        {
            StoreSelectFModule();
            if (SpriteBUS.CloneRowFModule(m_sprite, m_RowIndexFrame, m_RowIndexFModule))
                dgvFModules.CurrentCell = dgvFModules[3, dgvFModules.Rows.Count - 1];
        }
        private void btnFModule_SaveRow_Click(object sender, EventArgs e)
        {
            StoreSelectFModule();
            SpriteBUS.SaveRowFModule(m_sprite, m_RowIndexFrame, m_RowIndexFModule);
        }
        private void btnFModule_SaveAll_Click(object sender, EventArgs e)
        {
            SpriteBUS.SaveAllFModule(m_sprite, m_RowIndexFrame);
        }
        private void btnFModule_DelRow_Click(object sender, EventArgs e)
        {
            StoreSelectFModule();
            SpriteBUS.DelRowFModule(m_sprite, m_RowIndexFrame, m_RowIndexFModule);
        }
        private void btnFModule_Up_Click(object sender, EventArgs e)
        {
            StoreSelectFModule();
            int newCol = m_ColumnIndexFModule;
            int newRow = m_RowIndexFModule - 1;
            if (SpriteBUS.FModuleRowUp(m_sprite, m_RowIndexFrame, m_RowIndexFModule))
                dgvFModules.CurrentCell = dgvFModules[newCol, newRow];

        }

        private void btnFModule_Down_Click(object sender, EventArgs e)
        {
            StoreSelectFModule();
            int newCol = m_ColumnIndexFModule;
            int newRow = m_RowIndexFModule + 1;
            if (SpriteBUS.FModuleRowDown(m_sprite, m_RowIndexFrame, m_RowIndexFModule))
                dgvFModules.CurrentCell = dgvFModules[newCol, newRow];
        }
        private void dgvFModules_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 1)
            {
                int mid = -1;
                int iMid = -1;

                int.TryParse((string)dgvFModules[1, e.RowIndex].Value, NumberStyles.AllowHexSpecifier,
                    CultureInfo.InvariantCulture.NumberFormat, out mid);
                for (int i = 0; i < m_sprite.Modules.Count; i++)
                {
                    if (m_sprite.Modules[i].Id == mid)
                    {
                        iMid = i;
                        break;
                    }
                }
                if (iMid != -1)
                {
                    m_RowIndexModule = iMid;
                    grvModule.CurrentCell = grvModule[1, iMid];
                    tabTool.SelectedIndex = 0;
                }
            }
        }
        #endregion


        #region Animation
        int m_RowIndexAnimation;
        int m_ColumnIndexAnimation;
        private void StoreSelectAnimation()
        {
            if (dgvAnimation.SelectedCells.Count == 0)
            {
                m_RowIndexAnimation = -1;
                m_ColumnIndexAnimation = -1;
            }
            else
            {
                m_RowIndexAnimation = dgvAnimation.SelectedCells[0].RowIndex;
                m_ColumnIndexAnimation = dgvAnimation.SelectedCells[0].ColumnIndex;
            }
        }
        private void ReStoreSelectAnimation()
        {
            if (m_RowIndexAnimation >= dgvFrames.Rows.Count)
                m_RowIndexAnimation = dgvFrames.Rows.Count - 1;
            if (m_RowIndexAnimation < 0 || m_ColumnIndexAnimation < 0)
                return;
            dgvAnimation.CurrentCell = dgvAnimation[m_ColumnIndexAnimation, m_RowIndexAnimation];
        }
        private void dgvAnimation_SelectionChanged(object sender, EventArgs e)
        {
            StoreSelectAnimation();
            pnlImageViewer.Invalidate();
        }
        private void dgvAnimation_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            m_IsDrawBoundRect = false;
            m_RowIndexAnimation = e.RowIndex;
            m_ColumnIndexAnimation = e.ColumnIndex;
            dgvAFrames.DataSource = SpriteBUS.GetDataAFrame(m_sprite, m_RowIndexAnimation);
            timerFPS.Enabled = true;
        }
        private void dgvAnimation_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            int index = e.RowIndex;
            //SpriteBUS.SetEditAnimation(index);
            SpriteBUS.SaveRowAnimation(m_sprite, index);
            pnlImageViewer.Invalidate();
        }
        private void btnAnimation_NewRow_Click(object sender, EventArgs e)
        {
            SpriteBUS.NewRowAnimation(m_sprite);
            dgvAnimation.CurrentCell = dgvAnimation[3, dgvAnimation.Rows.Count - 1];
            dgvAFrames.DataSource = SpriteBUS.GetDataAFrame(m_sprite, dgvAnimation.Rows.Count - 1);
        }
        private void btnAnimation_Clone_Click(object sender, EventArgs e)
        {
            StoreSelectAnimation();
            if (SpriteBUS.CloneRowAnimation(m_sprite, m_RowIndexAnimation))
            {
                dgvAnimation.CurrentCell = dgvAnimation[3, dgvAnimation.Rows.Count - 1];
                dgvAFrames.DataSource = SpriteBUS.GetDataAFrame(m_sprite, dgvAnimation.Rows.Count - 1);
            }
        }
        private void btnAnimation_SaveRow_Click(object sender, EventArgs e)
        {
            StoreSelectAnimation();
            SpriteBUS.SaveRowAnimation(m_sprite, m_RowIndexAnimation);
        }
        private void btnAnimation_SaveAll_Click(object sender, EventArgs e)
        {
            SpriteBUS.SaveAllAnimation(m_sprite);
        }
        private void btnAnimation_DelRow_Click(object sender, EventArgs e)
        {
            StoreSelectAnimation();
            SpriteBUS.DelRowAnimation(m_sprite, m_RowIndexAnimation);
        }


        private void btnAnimation_Up_Click(object sender, EventArgs e)
        {
            StoreSelectAnimation();
            int newCol = m_ColumnIndexAnimation;
            int newRow = m_RowIndexAnimation - 1;
            if (SpriteBUS.AnimationRowUp(m_sprite, m_RowIndexAnimation))
                dgvAnimation.CurrentCell = dgvAnimation[newCol, newRow];
        }

        private void btnAnimation_Down_Click(object sender, EventArgs e)
        {
            StoreSelectAnimation();
            int newCol = m_ColumnIndexAnimation;
            int newRow = m_RowIndexAnimation + 1;
            if (SpriteBUS.AnimationRowDown(m_sprite, m_RowIndexAnimation))
                dgvAnimation.CurrentCell = dgvAnimation[newCol, newRow];
        }

        #endregion

        #region AFrame
        int m_RowIndexAFrame;
        int m_ColumnIndexAFrame;
        private void StoreSelectAFrame()
        {
            if (dgvAFrames.SelectedCells.Count == 0)
            {
                m_RowIndexAFrame = -1;
                m_ColumnIndexAFrame = -1;
            }
            else
            {
                m_RowIndexAFrame = dgvAFrames.SelectedCells[0].RowIndex;
                m_ColumnIndexAFrame = dgvAFrames.SelectedCells[0].ColumnIndex;
            }
        }
        private void ReStoreSelectAFrame()
        {
            if (m_RowIndexAFrame >= dgvAFrames.Rows.Count)
                m_RowIndexAFrame = dgvAFrames.Rows.Count - 1;
            if (m_RowIndexAFrame < 0 || m_ColumnIndexAFrame < 0)
                return;
            dgvAFrames.CurrentCell = dgvAFrames[m_ColumnIndexAFrame, m_RowIndexAFrame];
        }
        private void dgvAFrames_SelectionChanged(object sender, EventArgs e)
        {
            StoreSelectAFrame();
            if (m_RowIndexAnimation < 0 || m_RowIndexAnimation >= m_sprite.Animations.Count)
                return;
            m_sprite.Animations[m_RowIndexAnimation].CurFrame = m_RowIndexAFrame;
            pnlImageViewer.Invalidate();

        }
        private void dgvAFrames_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            m_IsDrawBoundRect = true;
            m_NeedTestMouseWithRect = true;
            m_RowIndexAFrame = e.RowIndex;
            m_ColumnIndexAFrame = e.ColumnIndex;
            timerFPS.Enabled = false;
            pnlImageViewer.Invalidate();
        }

        private void dgvAFrames_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            int index = e.RowIndex;
            //SpriteBUS.SetEditAFrame(index);
            SpriteBUS.SaveRowAFrame(m_sprite, m_RowIndexAnimation, index);
            pnlImageViewer.Invalidate();
        }
        private void btnAFrame_NewRow_Click(object sender, EventArgs e)
        {
            if (SpriteBUS.NewRowAFrame(m_sprite, m_RowIndexAnimation))
                dgvAFrames.CurrentCell = dgvAFrames[3, dgvAFrames.Rows.Count - 1];
        }

        private void btnAFrame_Clone_Click(object sender, EventArgs e)
        {
            StoreSelectAFrame();
            if (SpriteBUS.CloneRowAFrame(m_sprite, m_RowIndexAnimation, m_RowIndexAFrame))
                dgvAFrames.CurrentCell = dgvAFrames[3, dgvAFrames.Rows.Count - 1];
        }

        private void btnAFrame_SaveRow_Click(object sender, EventArgs e)
        {
            StoreSelectAFrame();
            SpriteBUS.SaveRowAFrame(m_sprite, m_RowIndexAnimation, m_RowIndexAFrame);
        }

        private void btnAFrame_SaveAll_Click(object sender, EventArgs e)
        {
            SpriteBUS.SaveAllAFrame(m_sprite, m_RowIndexAnimation);
        }

        private void btnAFrame_DelRow_Click(object sender, EventArgs e)
        {
            StoreSelectAFrame();
            SpriteBUS.DelRowAFrame(m_sprite, m_RowIndexAnimation, m_RowIndexAFrame);
        }

        private void btnAFrame_Up_Click(object sender, EventArgs e)
        {
            StoreSelectAFrame();
            int newCol = m_ColumnIndexAFrame;
            int newRow = m_RowIndexAFrame - 1;
            if (SpriteBUS.AFrameRowUp(m_sprite, m_RowIndexAnimation, m_RowIndexAFrame))
                dgvAFrames.CurrentCell = dgvAFrames[newCol, newRow];
        }

        private void btnAFrame_Down_Click(object sender, EventArgs e)
        {
            StoreSelectAFrame();
            int newCol = m_ColumnIndexAFrame;
            int newRow = m_RowIndexAFrame + 1;
            if (SpriteBUS.AFrameRowDown(m_sprite, m_RowIndexAnimation, m_RowIndexAFrame))
                dgvAFrames.CurrentCell = dgvAFrames[newCol, newRow];
        }

        private void dgvAFrames_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 1)
            {
                int fid = -1;
                int iFid = -1;

                int.TryParse((string)dgvAFrames[1, e.RowIndex].Value, NumberStyles.AllowHexSpecifier,
                    CultureInfo.InvariantCulture.NumberFormat, out fid);
                for (int i = 0; i < m_sprite.Frames.Count; i++)
                {
                    if (m_sprite.Frames[i].Id == fid)
                    {
                        iFid = i;
                        break;
                    }
                }
                if (iFid != -1)
                {
                    m_RowIndexFrame = iFid;
                    dgvFrames.CurrentCell = dgvFrames[1, iFid];
                    tabTool.SelectedIndex = 1;
                }
            }
        }
        #endregion

        #region ImageVierwer
        int m_ImageViewerPosX;
        int m_ImageViewerPosY;
        //float m_ImageViewerScale;
        Pen m_penAqua;
        Pen m_penLinearRed;
        Brush m_brGradient;
        bool m_ImageViewerIsRMouseDown = false;
        bool m_ImageViewerIsLMouseDown = false;
        Point m_ImageViewerROldClick = new Point();
        Point m_ImageViewerLOldClick = new Point();
        bool m_IsDrawBoundRect = false;
        float m_ScaleImageViewer = 1;
        public enum RelativeMouseInRect
        {
            None,
            InSize,
            Left,
            Right,
            Bottom,
            Top,
            TopLeft,
            TopRight,
            BottomLeft,
            BottomRight,
            OutSize,
        }
        RelativeMouseInRect m_MouseState;
        private void PaintModuleState(Graphics g)
        {
            if (m_sprite.ImageInfo.Count > 0)
            {
                Bitmap image = m_sprite.ImageInfo[0].Image;
                if (image != null)
                {
                    Rectangle srcRec = new Rectangle(0, 0, image.Width, image.Height);
                    Rectangle desRec = new Rectangle(m_ImageViewerPosX - (int)(m_ScaleImageViewer), m_ImageViewerPosY - (int)(m_ScaleImageViewer), (int)(image.Width * m_ScaleImageViewer), (int)(image.Height * m_ScaleImageViewer));
                    desRec.X += (int)(m_ScaleImageViewer);
                    desRec.Y += (int)(m_ScaleImageViewer);
                    g.InterpolationMode = InterpolationMode.NearestNeighbor;
                    g.DrawImage(image, desRec, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, m_sprite.ImageInfo[0].ImageAttr);
                    //if (m_ScaleImageViewer < 2)
                    //    g.DrawImage(image, desRec, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, m_sprite.ImageInfo[0].ImageAttr);
                    //else
                    //{
                    //    Bitmap b = m_sprite.ImageInfo[0].CacheScaleImage(m_ScaleImageViewer);
                    //    g.DrawImage(b, desRec, 0, 0, desRec.Width, desRec.Height, GraphicsUnit.Pixel, m_sprite.ImageInfo[0].ImageAttr);
                    //}
                }
            }
            if (m_RowIndexModule >= 0 && m_RowIndexModule < m_sprite.Modules.Count)
            {
                Module module = m_sprite.Modules[m_RowIndexModule];

                g.DrawRectangle(m_penLinearRed,
                    (m_ImageViewerPosX + module.X * m_ScaleImageViewer - m_ScaleImageViewer / 2),
                    (m_ImageViewerPosY + module.Y * m_ScaleImageViewer - m_ScaleImageViewer / 2),
                    (module.W * m_ScaleImageViewer),
                    (module.H * m_ScaleImageViewer));
            }
        }
        private void PaintFrameState(Graphics g)
        {
            if (m_RowIndexFrame >= 0 && m_RowIndexFrame < m_sprite.Frames.Count)
            {
                Frame frame = m_sprite.Frames[m_RowIndexFrame];
                m_sprite.PaintFrame(g, frame, m_ImageViewerPosX, m_ImageViewerPosY, 0, m_ScaleImageViewer);
                if (m_IsDrawBoundRect && m_RowIndexFModule >= 0 && m_RowIndexFModule < frame.FModules.Count)
                {
                    FModule fmodule = frame.FModules[m_RowIndexFModule];
                    Module module = m_sprite.GetModule(fmodule.Mid);
                    if (module == null)
                        return;



                    float rot = 0;

                    if ((fmodule.Flag & SpriteDTO.ROTATE_180) != 0)
                        if ((fmodule.Flag & SpriteDTO.ROTATE_90) != 0)
                            rot = 270;
                        else
                            rot = 180;
                    else
                        if ((fmodule.Flag & SpriteDTO.ROTATE_90) != 0)
                            rot = 90;
                    g.TranslateTransform(m_ImageViewerPosX + fmodule.Ox * m_ScaleImageViewer, m_ImageViewerPosY + fmodule.Oy * m_ScaleImageViewer);
                    g.RotateTransform(rot);
                    g.DrawRectangle(m_penLinearRed,
                        0,
                        0,
                        module.W * m_ScaleImageViewer,
                        module.H * m_ScaleImageViewer);

                    g.TranslateTransform(-(m_ImageViewerPosX + fmodule.Ox * m_ScaleImageViewer), -(m_ImageViewerPosY + fmodule.Oy * m_ScaleImageViewer));
                    g.RotateTransform(-rot);
                }
            }
        }
        private void PaintAnimationState(Graphics g)
        {
            if (m_RowIndexAnimation >= 0 && m_RowIndexAnimation < m_sprite.Animations.Count)
            {
                Animation animation = m_sprite.Animations[m_RowIndexAnimation];
                m_sprite.PaintAndUpdateAnimation(g, animation, m_ImageViewerPosX, m_ImageViewerPosY, m_ScaleImageViewer);
                if (m_IsDrawBoundRect && m_RowIndexAFrame >= 0 && m_RowIndexAFrame < animation.AFrames.Count)
                {
                    AFrame aframe = animation.AFrames[m_RowIndexAFrame];
                    Frame frame = m_sprite.GetFrame(aframe.Fid);


                    g.DrawRectangle(m_penLinearRed,
                        m_ImageViewerPosX + (aframe.Ox - m_sprite.GetPadX(frame)) * m_ScaleImageViewer,
                        m_ImageViewerPosY + (aframe.Oy - m_sprite.GetPadY(frame)) * m_ScaleImageViewer,
                        m_sprite.GetFrameWidth(frame) * m_ScaleImageViewer,
                        m_sprite.GetFrameHeight(frame) * m_ScaleImageViewer);
                }
            }
        }

        private void pnlImageViewer_Paint(object sender, PaintEventArgs e)
        {
            Bitmap buffer = new Bitmap(pnlImageViewer.Width, pnlImageViewer.Height);
            Graphics g = Graphics.FromImage(buffer);
            g.FillRectangle(new SolidBrush(m_option.GroundImageViewColor), 0, 0, pnlImageViewer.Width, pnlImageViewer.Height);
            //Graphics g = e.Graphics;
            if (m_ImageViewerPosX >= 0 && m_ImageViewerPosX <= Width)
            {
                g.DrawLine(m_penAqua, m_ImageViewerPosX - (int)(m_ScaleImageViewer / 2), 0, m_ImageViewerPosX - (int)(m_ScaleImageViewer / 2), Height);
            }
            if (m_ImageViewerPosY >= 0 && m_ImageViewerPosY <= Width)
            {
                g.DrawLine(m_penAqua, 0, m_ImageViewerPosY - (int)(m_ScaleImageViewer / 2), Width, m_ImageViewerPosY - (int)(m_ScaleImageViewer / 2));
            }

            if (m_option.IsUseGrid)
            {
                int i = (m_ImageViewerPosX % (int)(m_option.GridSize * m_ScaleImageViewer)) - (int)(m_ScaleImageViewer / 2);
                int j = (m_ImageViewerPosY % (int)(m_option.GridSize * m_ScaleImageViewer)) - (int)(m_ScaleImageViewer / 2);


                while (i < pnlImageViewer.Width)
                {
                    g.DrawLine(m_penAqua, i, 0, i, pnlImageViewer.Height);
                    i += (int)(m_option.GridSize * m_ScaleImageViewer);
                }
                while (j < pnlImageViewer.Width)
                {
                    g.DrawLine(m_penAqua, 0, j, pnlImageViewer.Width, j);
                    j += (int)(m_option.GridSize * m_ScaleImageViewer);
                }

            }

            switch (tabTool.SelectedIndex)
            {
                case 0: //Module
                    PaintModuleState(g);
                    break;
                case 1: //Frame
                    PaintFrameState(g);
                    break;
                case 2: //Animation
                    PaintAnimationState(g);
                    break;
            }
            e.Graphics.DrawImageUnscaled(buffer, 0, 0);
            g.Dispose();
        }

        private void pnlImageViewer_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                if (m_ImageViewerIsRMouseDown == false)
                {
                    m_ImageViewerIsRMouseDown = true;
                    m_ImageViewerROldClick.X = e.X;
                    m_ImageViewerROldClick.Y = e.Y;
                }
            }
            else if (e.Button == MouseButtons.Left)
            {
                if (m_ImageViewerIsLMouseDown == false)
                {
                    m_ImageViewerIsLMouseDown = true;
                    m_ImageViewerLOldClick.X = e.X;
                    m_ImageViewerLOldClick.Y = e.Y;
                    m_NeedTestMouseWithRect = false;

                    if (tabTool.SelectedIndex == 0)
                    {
                        int rs = SpriteBUS.FindModuleContainPoint(m_sprite, (int)((e.X - m_ImageViewerPosX) / m_ScaleImageViewer), (int)((e.Y - m_ImageViewerPosY) / m_ScaleImageViewer));
                        if (rs != -1 && rs != m_RowIndexModule)
                        {
                            m_RowIndexModule = rs;
                            m_IsDrawBoundRect = true;
                            m_NeedTestMouseWithRect = true;
                            ReStoreSelectModule();
                            pnlImageViewer.Invalidate();
                        }
                    }
                    else if (tabTool.SelectedIndex == 1)
                    {
                        int rs = SpriteBUS.FindFModuleContainPoint(m_sprite, m_RowIndexFrame, (int)((e.X - m_ImageViewerPosX) / m_ScaleImageViewer), (int)((e.Y - m_ImageViewerPosY) / m_ScaleImageViewer), m_RowIndexFModule);
                        if (rs != -1 && rs != m_RowIndexFModule)
                        {
                            m_RowIndexFModule = rs;
                            m_IsDrawBoundRect = true;
                            m_NeedTestMouseWithRect = true;
                            ReStoreSelectFModule();
                            pnlImageViewer.Invalidate();
                        }
                    }
                }
            }
        }
        private void TestMouseWithRect(int X, int Y)
        {
            Rectangle boundRect = new Rectangle();
            Cursor cur = null;
            if (tabTool.SelectedIndex == 0)
            {
                if (m_RowIndexModule < 0 || m_RowIndexModule >= m_sprite.Modules.Count)
                    return;
                Module module = m_sprite.Modules[m_RowIndexModule];
                boundRect = new Rectangle(
                    (int)(m_ImageViewerPosX + module.X * m_ScaleImageViewer),
                    (int)(m_ImageViewerPosY + module.Y * m_ScaleImageViewer),
                    (int)(module.W * m_ScaleImageViewer),
                    (int)(module.H * m_ScaleImageViewer));
            }
            else if (tabTool.SelectedIndex == 1)
            {
                if (m_RowIndexFrame < 0 || m_RowIndexFrame >= m_sprite.Frames.Count ||
                    m_RowIndexFModule < 0 || m_RowIndexFModule >= m_sprite.Frames[m_RowIndexFrame].FModules.Count)
                    return;
                FModule fmodule = m_sprite.Frames[m_RowIndexFrame].FModules[m_RowIndexFModule];
                Module module = m_sprite.GetModule(fmodule.Mid);
                if (module == null)
                    return;
                fmodule.Module = module;
                int rot = 0;
                if ((fmodule.Flag & SpriteDTO.ROTATE_180) != 0)
                    if ((fmodule.Flag & SpriteDTO.ROTATE_90) != 0)
                        rot = 270;
                    else
                        rot = 180;
                else
                    if ((fmodule.Flag & SpriteDTO.ROTATE_90) != 0)
                        rot = 90;
                Rectangle rect = new Rectangle(fmodule.Ox,
                    fmodule.Oy,
                    fmodule.Module.W,
                    fmodule.Module.H);

                if (rot == 90)
                {
                    rect.X -= fmodule.Module.H;
                    rect.Width = fmodule.Module.H;
                    rect.Height = fmodule.Module.W;
                }
                else if (rot == 180)
                {
                    rect.X -= fmodule.Module.W;
                    rect.Y -= fmodule.Module.H;
                }
                else if (rot == 270)
                {
                    rect.Y -= fmodule.Module.W;
                    rect.Width = fmodule.Module.H;
                    rect.Height = fmodule.Module.W;
                }
                boundRect = new Rectangle(
                   (int)(m_ImageViewerPosX + rect.X * m_ScaleImageViewer),
                   (int)(m_ImageViewerPosY + rect.Y * m_ScaleImageViewer),
                   (int)(rect.Width * m_ScaleImageViewer),
                   (int)(rect.Height * m_ScaleImageViewer));
            }
            else if (tabTool.SelectedIndex == 2)
            {
                if (m_RowIndexAnimation < 0 || m_RowIndexAnimation >= m_sprite.Animations.Count ||
                    m_RowIndexAFrame < 0 || m_RowIndexAFrame >= m_sprite.Animations[m_RowIndexAnimation].AFrames.Count)
                    return;
                AFrame aframe = m_sprite.Animations[m_RowIndexAnimation].AFrames[m_RowIndexAFrame];
                Frame frame = m_sprite.GetFrame(aframe.Fid);
                if (frame == null)
                    return;

                boundRect = new Rectangle(
                   (int)(m_ImageViewerPosX + (aframe.Ox - m_sprite.GetPadX(frame)) * m_ScaleImageViewer),
                   (int)(m_ImageViewerPosY + (aframe.Oy - m_sprite.GetPadY(frame)) * m_ScaleImageViewer),
                   (int)(m_sprite.GetFrameWidth(frame) * m_ScaleImageViewer),
                   (int)(m_sprite.GetFrameHeight(frame) * m_ScaleImageViewer));
            }

            if (X >= boundRect.Left &&
                    X <= boundRect.Right &&
                   Y >= boundRect.Top &&
                   Y <= boundRect.Bottom)
            {
                m_MouseState = RelativeMouseInRect.InSize;
                cur = Cursors.SizeAll;
            }
            else
            {
                m_MouseState = RelativeMouseInRect.OutSize;
            }
            if (tabTool.SelectedIndex == 0)
            {

                if (IsNear(X, boundRect.Left) && (Y - boundRect.Top >= -2 && boundRect.Bottom - Y >= -2))
                {
                    m_MouseState = RelativeMouseInRect.Left;
                    cur = Cursors.SizeWE;
                    if (IsNear(Y, boundRect.Top))
                    {
                        m_MouseState = RelativeMouseInRect.TopLeft;
                        cur = Cursors.SizeNWSE;
                    }
                    if (IsNear(Y, boundRect.Bottom))
                    {
                        m_MouseState = RelativeMouseInRect.BottomLeft;
                        cur = Cursors.SizeNESW;
                    }
                }
                else if (IsNear(X, boundRect.Right) && (Y - boundRect.Top >= -2 && boundRect.Bottom - Y >= -2))
                {
                    m_MouseState = RelativeMouseInRect.Right;
                    cur = Cursors.SizeWE;
                    if (IsNear(Y, boundRect.Top) && (X - boundRect.Left >= -2 && boundRect.Right - X >= -2))
                    {
                        m_MouseState = RelativeMouseInRect.TopRight;
                        cur = Cursors.SizeNESW;
                    }
                    if (IsNear(Y, boundRect.Bottom) && (X - boundRect.Left >= -2 && boundRect.Right - X >= -2))
                    {
                        m_MouseState = RelativeMouseInRect.BottomRight;
                        cur = Cursors.SizeNWSE;
                    }
                }
                else if (IsNear(Y, boundRect.Top) && (X - boundRect.Left >= -2 && boundRect.Right - X >= -2))
                {
                    m_MouseState = RelativeMouseInRect.Top;
                    cur = Cursors.SizeNS;
                }
                else if (IsNear(Y, boundRect.Bottom) && (X - boundRect.Left >= -2 && boundRect.Right - X >= -2))
                {
                    m_MouseState = RelativeMouseInRect.Bottom;
                    cur = Cursors.SizeNS;
                }
            }
            pnlImageViewer.Cursor = cur;
        }
        private bool IsNear(int a, int b)
        {
            return Math.Abs(a - b) <= 2;
        }
        bool m_NeedTestMouseWithRect = false;
        private void pnlImageViewer_MouseMove(object sender, MouseEventArgs e)
        {
            if (m_IsDrawBoundRect && m_NeedTestMouseWithRect)
            {
                TestMouseWithRect(e.X, e.Y);
            }
            if (e.Button == MouseButtons.Right)
            {
                if (m_ImageViewerIsRMouseDown == true)
                {
                    int deltaX = e.X - m_ImageViewerROldClick.X;
                    int deltaY = e.Y - m_ImageViewerROldClick.Y;

                    bool flag = false;
                    if (deltaX >= 2 || deltaX <= -2)
                    {
                        m_ImageViewerPosX += deltaX;
                        m_ImageViewerROldClick.X = e.X;
                        flag = true;
                    }
                    if (deltaY >= 2 || deltaY <= -2)
                    {
                        m_ImageViewerPosY += deltaY;
                        m_ImageViewerROldClick.Y = e.Y;
                        flag = true;
                    }
                    if (flag)
                    {
                        pnlImageViewer.Invalidate();
                    }
                }
            }
            if (e.Button == MouseButtons.Left)
            {
                if (m_IsDrawBoundRect)
                {
                    if (m_ImageViewerIsLMouseDown == true)
                    {
                        if (tabTool.SelectedIndex == 0)
                        {
                            ImageViewerOnMoveModule(e.X, e.Y);
                        }
                        else if (tabTool.SelectedIndex == 1)
                        {
                            ImageViewerOnMoveFrame(e.X, e.Y);
                        }
                        else if (tabTool.SelectedIndex == 2)
                        {
                            ImageViewerOnMoveAnimation(e.X, e.Y);
                        }
                    }
                }
            }
        }
        private void ImageViewerOnMoveModule(int X, int Y)
        {
            if (m_RowIndexModule < 0 || m_RowIndexModule >= m_sprite.Modules.Count)
                return;
            Module module = m_sprite.Modules[m_RowIndexModule];

            //Rectangle boundRect = new Rectangle(
            //    (int)(m_ImageViewerPosX + module.X * m_ScaleImageViewer),
            //    (int)(m_ImageViewerPosY + module.Y * m_ScaleImageViewer),
            //    (int)(module.W * m_ScaleImageViewer),
            //    (int)(module.H * m_ScaleImageViewer));
            //if (X >= boundRect.Left &&
            //    X <= boundRect.Right &&
            //    Y >= boundRect.Top &&
            //    Y <= boundRect.Bottom)
            int deltaX = (int)((X - m_ImageViewerLOldClick.X) / m_ScaleImageViewer);
            int deltaY = (int)((Y - m_ImageViewerLOldClick.Y) / m_ScaleImageViewer);
            bool flag = false;
            if (m_MouseState == RelativeMouseInRect.InSize)
            {

                if (Math.Abs(deltaX) >= 1)
                {
                    grvModule.Rows[m_RowIndexModule].Cells["X"].Value = module.X + deltaX;
                    m_ImageViewerLOldClick.X = X;
                    flag = true;
                }
                if (Math.Abs(deltaY) >= 1)
                {
                    grvModule.Rows[m_RowIndexModule].Cells["Y"].Value = module.Y + deltaY;
                    m_ImageViewerLOldClick.Y = Y;
                    flag = true;
                }
            }
            if (m_MouseState == RelativeMouseInRect.Left ||
                m_MouseState == RelativeMouseInRect.TopLeft ||
                m_MouseState == RelativeMouseInRect.BottomLeft)
            {
                if (Math.Abs(deltaX) >= 1)
                {
                    grvModule.Rows[m_RowIndexModule].Cells["W"].Value = module.W - deltaX;
                    grvModule.Rows[m_RowIndexModule].Cells["X"].Value = module.X + deltaX;
                    m_ImageViewerLOldClick.X = X;
                    flag = true;
                }
            }
            if (m_MouseState == RelativeMouseInRect.Right ||
                m_MouseState == RelativeMouseInRect.TopRight ||
                m_MouseState == RelativeMouseInRect.BottomRight)
            {
                if (Math.Abs(deltaX) >= 1)
                {
                    grvModule.Rows[m_RowIndexModule].Cells["W"].Value = module.W + deltaX;
                    m_ImageViewerLOldClick.X = X;
                    flag = true;
                }
            }
            if (m_MouseState == RelativeMouseInRect.Top ||
                m_MouseState == RelativeMouseInRect.TopLeft ||
                m_MouseState == RelativeMouseInRect.TopRight)
            {
                if (Math.Abs(deltaY) >= 1)
                {
                    grvModule.Rows[m_RowIndexModule].Cells["H"].Value = module.H - deltaY;
                    grvModule.Rows[m_RowIndexModule].Cells["Y"].Value = module.Y + deltaY;
                    m_ImageViewerLOldClick.Y = Y;
                    flag = true;
                }
            }
            if (m_MouseState == RelativeMouseInRect.Bottom ||
                m_MouseState == RelativeMouseInRect.BottomLeft ||
                m_MouseState == RelativeMouseInRect.BottomRight)
            {
                if (Math.Abs(deltaY) >= 1)
                {
                    grvModule.Rows[m_RowIndexModule].Cells["H"].Value = module.H + deltaY;
                    m_ImageViewerLOldClick.Y = Y;
                    flag = true;
                }
            }

            if (flag)
            {
                SpriteBUS.SaveRowModule(m_sprite, m_RowIndexModule);
                pnlImageViewer.Invalidate();
                m_wasSpriteChange = true;
            }
        }
        private void ImageViewerOnMoveFrame(int X, int Y)
        {
            if (m_RowIndexFrame < 0 || m_RowIndexFrame >= m_sprite.Frames.Count ||
                m_RowIndexFModule < 0 || m_RowIndexFModule >= m_sprite.Frames[m_RowIndexFrame].FModules.Count)
                return;
            FModule fmodule = m_sprite.Frames[m_RowIndexFrame].FModules[m_RowIndexFModule];
            Module module = m_sprite.GetModule(fmodule.Mid);
            if (module == null)
                return;
            fmodule.Module = module;
            int rot = 0;
            if ((fmodule.Flag & SpriteDTO.ROTATE_180) != 0)
                if ((fmodule.Flag & SpriteDTO.ROTATE_90) != 0)
                    rot = 270;
                else
                    rot = 180;
            else
                if ((fmodule.Flag & SpriteDTO.ROTATE_90) != 0)
                    rot = 90;
            Rectangle rect = new Rectangle(fmodule.Ox,
                fmodule.Oy,
                fmodule.Module.W,
                fmodule.Module.H);

            if (rot == 90)
            {
                rect.X -= fmodule.Module.H;
                rect.Width = fmodule.Module.H;
                rect.Height = fmodule.Module.W;
            }
            else if (rot == 180)
            {
                rect.X -= fmodule.Module.W;
                rect.Y -= fmodule.Module.H;
            }
            else if (rot == 270)
            {
                rect.Y -= fmodule.Module.W;
                rect.Width = fmodule.Module.H;
                rect.Height = fmodule.Module.W;
            }


            //Rectangle boundRect = new Rectangle(
            //   (int)(m_ImageViewerPosX + fmodule.Ox * m_ScaleImageViewer),
            //   (int)(m_ImageViewerPosY + fmodule.Oy * m_ScaleImageViewer),
            //   (int)(module.W * m_ScaleImageViewer),
            //   (int)(module.H * m_ScaleImageViewer));
            //if (X >= boundRect.Left &&
            //    X <= boundRect.Right &&
            //    Y >= boundRect.Top &&
            //    Y <= boundRect.Bottom)
            if (m_MouseState == RelativeMouseInRect.InSize)
            {
                int deltaX = (int)((X - m_ImageViewerLOldClick.X) / m_ScaleImageViewer);
                int deltaY = (int)((Y - m_ImageViewerLOldClick.Y) / m_ScaleImageViewer);

                bool flag = false;
                if (Math.Abs(deltaX) >= 1)
                {

                    dgvFModules.Rows[m_RowIndexFModule].Cells["Ox"].Value = fmodule.Ox + deltaX;
                    m_ImageViewerLOldClick.X = X;
                    flag = true;
                }
                if (Math.Abs(deltaY) >= 1)
                {
                    dgvFModules.Rows[m_RowIndexFModule].Cells["Oy"].Value = fmodule.Oy + deltaY;
                    m_ImageViewerLOldClick.Y = Y;
                    flag = true;
                }
                if (flag)
                {
                    SpriteBUS.SaveRowFModule(m_sprite, m_RowIndexFrame, m_RowIndexFModule);
                    pnlImageViewer.Invalidate();
                    m_wasSpriteChange = true;
                }
            }
        }
        private void ImageViewerOnMoveAnimation(int X, int Y)
        {
            if (m_RowIndexAnimation < 0 || m_RowIndexAnimation >= m_sprite.Animations.Count ||
                m_RowIndexAFrame < 0 || m_RowIndexAFrame >= m_sprite.Animations[m_RowIndexAnimation].AFrames.Count)
                return;
            AFrame aframe = m_sprite.Animations[m_RowIndexAnimation].AFrames[m_RowIndexAFrame];
            Frame frame = m_sprite.GetFrame(aframe.Fid);
            if (frame == null)
                return;

            //Rectangle boundRect = new Rectangle(
            //   (int)(m_ImageViewerPosX + (aframe.Ox - m_sprite.GetPadX(frame)) * m_ScaleImageViewer),
            //   (int)(m_ImageViewerPosY + (aframe.Oy - m_sprite.GetPadY(frame)) * m_ScaleImageViewer),
            //   (int)(m_sprite.GetFrameWidth(frame) * m_ScaleImageViewer),
            //   (int)(m_sprite.GetFrameHeight(frame) * m_ScaleImageViewer));
            //if (X >= boundRect.Left &&
            //    X <= boundRect.Right &&
            //    Y >= boundRect.Top &&
            //    Y <= boundRect.Bottom)
            if (m_MouseState == RelativeMouseInRect.InSize)
            {
                int deltaX = (int)((X - m_ImageViewerLOldClick.X) / m_ScaleImageViewer);
                int deltaY = (int)((Y - m_ImageViewerLOldClick.Y) / m_ScaleImageViewer);

                bool flag = false;
                if (Math.Abs(deltaX) >= 1)
                {

                    dgvAFrames.Rows[m_RowIndexAFrame].Cells["Ox"].Value = aframe.Ox + deltaX;
                    m_ImageViewerLOldClick.X = X;
                    flag = true;
                }
                if (Math.Abs(deltaY) >= 1)
                {
                    dgvAFrames.Rows[m_RowIndexAFrame].Cells["Oy"].Value = aframe.Oy + deltaY;
                    m_ImageViewerLOldClick.Y = Y;
                    flag = true;
                }
                if (flag)
                {
                    SpriteBUS.SaveRowAFrame(m_sprite, m_RowIndexAnimation, m_RowIndexAFrame);
                    pnlImageViewer.Invalidate();
                    m_wasSpriteChange = true;
                }
            }
        }


        private void pnlImageViewer_MouseUp(object sender, MouseEventArgs e)
        {

            if (e.Button == MouseButtons.Right)
            {
                if (m_ImageViewerIsRMouseDown == true)
                {
                    m_ImageViewerIsRMouseDown = false;
                }
            }
            else if (e.Button == MouseButtons.Left)
            {
                if (m_ImageViewerIsLMouseDown == true)
                {
                    m_ImageViewerIsLMouseDown = false;
                    m_MouseState = RelativeMouseInRect.None;
                    pnlImageViewer.Cursor = Cursors.Default;
                    m_NeedTestMouseWithRect = true;

                    if (m_wasSpriteChange)
                    {
                        m_wasSpriteChange = false;
                        SpriteStore();
                    }
                }
            }

        }
        private void pnlImageViewer_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (tabTool.SelectedIndex == 0)
            {


                Rectangle boundRect = SpriteBUS.GetBoundRect(m_sprite, (int)((e.X - m_ImageViewerPosX) / m_ScaleImageViewer),
                    (int)((e.Y - m_ImageViewerPosY) / m_ScaleImageViewer));
                SpriteBUS.NewRowModule(m_sprite, boundRect);
                RefreshDataGrid();
                grvModule.CurrentCell = grvModule[3, grvModule.Rows.Count - 1];
                m_RowIndexModule = grvModule.Rows.Count - 1;
                m_IsDrawBoundRect = true;
                m_NeedTestMouseWithRect = true;
                pnlImageViewer.Invalidate();
            }
        }
        private void trbZoomImageViwer_ValueChanged(object sender, EventArgs e)
        {
            switch (trbZoomImageViwer.Value)
            {
                case 0:
                    m_ScaleImageViewer = 0.1f;
                    break;
                case 1:
                    m_ScaleImageViewer = 0.2f;
                    break;
                case 2:
                    m_ScaleImageViewer = 0.333333f;
                    break;
                case 3:
                    m_ScaleImageViewer = 0.5f;
                    break;
                case 4:
                    m_ScaleImageViewer = 0.75f;
                    break;
                case 5:
                    m_ScaleImageViewer = 1f;
                    break;
                case 6:
                    m_ScaleImageViewer = 1.5f;
                    break;
                case 7:
                    m_ScaleImageViewer = 2f;
                    break;
                case 8:
                    m_ScaleImageViewer = 4f;
                    break;
                case 9:
                    m_ScaleImageViewer = 6f;
                    break;
                case 10:
                    m_ScaleImageViewer = 8f;
                    break;
            }
            lblZoomPercentImageViewer.Text = string.Format("Zoom: {0}%", (int)(100 * m_ScaleImageViewer));
            if (m_ScaleImageViewer > 1)
            {
                //m_penLinearRed.Width = m_ScaleImageViewer;
            }
            else
            {
                m_penLinearRed.Width = 1;
            }
            pnlImageViewer.Invalidate();
        }
        private void btnImageViewerCenter_Click(object sender, EventArgs e)
        {
            m_ImageViewerPosX = pnlImageViewer.Width / 2;
            m_ImageViewerPosY = pnlImageViewer.Height / 2;
            pnlImageViewer.Invalidate();
        }
        #endregion

        #region ImageModuleList
        public const int PADDING = 50;
        private int m_HScroolWidth;
        private int m_PadImageModuleList;
        List<int> m_HSCroolImageModuleWidth = new List<int>();
        int m_SelectedImageMoodule = -1;
        private void PaintFrameListState(Graphics g)
        {
            Point drawPoint = new Point(-m_PadImageModuleList, 0);
            int pad = 0;
            for (int i = 0; i < m_sprite.Modules.Count; i++)
            {
                Module module = m_sprite.Modules[i];
                pad = (PADDING - module.W) / 2;
                if (pad < 0)
                    pad = 1;
                drawPoint.X += pad;
                drawPoint.Y = (pnlImageMuduleList.Height - hsbImageModuleList.Height - module.H) / 2;

                if (m_SelectedImageMoodule == i)
                {
                    g.FillRectangle(Brushes.Gray, drawPoint.X - pad, 0, module.W + 2 * pad, pnlImageMuduleList.Height - hsbImageModuleList.Height);
                }

                m_sprite.PaintModule(g, module, drawPoint.X, drawPoint.Y, 0);

                g.DrawString("(" + i.ToString() + ")" + module.Id.ToString("x"), Font, Brushes.Black, new Point(drawPoint.X - pad, 10));

                drawPoint.X += module.W + pad;

                g.DrawLine(m_penAqua, drawPoint.X, 0, drawPoint.X, pnlImageMuduleList.Height - hsbImageModuleList.Height);
            }
        }
        private void PaintAnimationListState(Graphics g)
        {
            Point drawPoint = new Point(-m_PadImageModuleList, 0);
            int pad = 0;
            for (int i = 0; i < m_sprite.Frames.Count; i++)
            {
                Frame frame = m_sprite.Frames[i];
                pad = (PADDING - m_sprite.GetFrameWidth(frame)) / 2;
                if (pad < 0)
                    pad = 1;
                drawPoint.X += pad;
                drawPoint.Y = (pnlImageMuduleList.Height - hsbImageModuleList.Height - m_sprite.GetFrameHeight(frame)) / 2;

                if (m_SelectedImageMoodule == i)
                {
                    g.FillRectangle(Brushes.Gray, drawPoint.X - pad, 0, m_sprite.GetFrameWidth(frame) + 2 * pad, pnlImageMuduleList.Height - hsbImageModuleList.Height);
                }
                m_sprite.PaintFrame(g, frame, drawPoint.X + m_sprite.GetPadX(frame), drawPoint.Y + m_sprite.GetPadY(frame), 0);

                //Draw string

                g.DrawString("(" + i.ToString() + ")" + frame.Id.ToString("x"), Font, Brushes.Black, new Point(drawPoint.X - pad, 10));

                drawPoint.X += m_sprite.GetFrameWidth(frame) + pad;

                g.DrawLine(m_penAqua, drawPoint.X, 0, drawPoint.X, pnlImageMuduleList.Height - hsbImageModuleList.Height);


            }
        }

        private void pnlImageMuduleList_Paint(object sender, PaintEventArgs e)
        {
            Bitmap buffer = new Bitmap(pnlImageMuduleList.Width, pnlImageMuduleList.Height);
            Graphics g = Graphics.FromImage(buffer);
            g.FillRectangle(Brushes.White, 0, 0, pnlImageMuduleList.Width, pnlImageMuduleList.Height);

            g.FillRectangle(m_brGradient, 0, 0, pnlImageMuduleList.Width, pnlImageMuduleList.Height - hsbImageModuleList.Height);
            switch (tabTool.SelectedIndex)
            {
                case 0: //Module
                    //PaintModuleListState(g);
                    break;
                case 1: //Frame
                    PaintFrameListState(g);
                    break;
                case 2: //Animation
                    PaintAnimationListState(g);
                    break;
            }
            e.Graphics.DrawImageUnscaled(buffer, 0, 0);
            g.Dispose();
        }

        private void InitHScrool()
        {
            m_HScroolWidth = 0;
            m_HSCroolImageModuleWidth.Clear();
            int pad = 0;

            if (tabTool.SelectedIndex == 1)
            {
                for (int i = 0; i < m_sprite.Modules.Count; i++)
                {
                    Module module = m_sprite.Modules[i];
                    pad = (PADDING - module.W) / 2;
                    if (pad < 0)
                        pad = 1;
                    m_HScroolWidth += pad;

                    m_HScroolWidth += module.W + pad;
                    m_HSCroolImageModuleWidth.Add(m_HScroolWidth);
                }
            }
            else if (tabTool.SelectedIndex == 2)
            {
                for (int i = 0; i < m_sprite.Frames.Count; i++)
                {
                    Frame frame = m_sprite.Frames[i];
                    pad = (PADDING - m_sprite.GetFrameWidth(frame)) / 2;
                    if (pad < 0)
                        pad = 1;
                    m_HScroolWidth += pad;


                    m_HScroolWidth += m_sprite.GetFrameWidth(frame) + pad;
                    m_HSCroolImageModuleWidth.Add(m_HScroolWidth);
                }
            }
            //float ratio = iWidthDraw / (1.0f * pnlImageMuduleList.Width);                       
        }

        private void hsbImageModuleList_ValueChanged(object sender, EventArgs e)
        {
            m_PadImageModuleList = (m_HScroolWidth - pnlImageMuduleList.Width) * hsbImageModuleList.Value / (hsbImageModuleList.Maximum - hsbImageModuleList.LargeChange);
            pnlImageMuduleList.Invalidate();
        }
        private void pnlImageMuduleList_MouseDown(object sender, MouseEventArgs e)
        {
            int posX = e.X;
            m_SelectedImageMoodule = 0;
            for (int i = 0; i < m_HSCroolImageModuleWidth.Count; i++)
            {
                if (m_PadImageModuleList + posX > m_HSCroolImageModuleWidth[i])
                {
                    m_SelectedImageMoodule = i + 1;
                }
                else
                {
                    break;
                }
            }
            pnlImageMuduleList.Invalidate();
        }
        private void pnlImageMuduleList_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            if (tabTool.SelectedIndex == 1)
            {
                int mid = m_sprite.Modules[m_SelectedImageMoodule].Id;
                if (SpriteBUS.NewRowFModule(m_sprite, m_RowIndexFrame, mid))
                    dgvFModules.CurrentCell = dgvFModules[3, dgvFModules.Rows.Count - 1];
            }
            else if (tabTool.SelectedIndex == 2)
            {
                int fid = m_sprite.Frames[m_SelectedImageMoodule].Id;
                if (SpriteBUS.NewRowAFrame(m_sprite, m_RowIndexAnimation, fid))
                    dgvAFrames.CurrentCell = dgvAFrames[3, dgvAFrames.Rows.Count - 1];
            }
        }
        #endregion
        private void nudFBS_ValueChanged(object sender, EventArgs e)
        {
            timerFPS.Interval = (int)nudFBS.Value;
        }
        private void tabTool_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabTool.SelectedIndex == 2)
            {
                timerFPS.Interval = (int)nudFBS.Value;
                timerFPS.Enabled = true;
                lblFBS.Visible = true;
                nudFBS.Visible = true;
            }
            else
            {
                timerFPS.Enabled = false;
                lblFBS.Visible = false;
                nudFBS.Visible = false;
            }

            m_IsDrawBoundRect = false;

            InitHScrool();
            pnlImageViewer.Invalidate();
            pnlImageMuduleList.Invalidate();
        }
        private void timerFPS_Tick(object sender, EventArgs e)
        {
            if (m_RowIndexAnimation >= 0 && m_RowIndexAnimation < m_sprite.Animations.Count)
            {
                Animation animation = m_sprite.Animations[m_RowIndexAnimation];
                animation.UpdateAnimation();
                pnlImageViewer.Invalidate();
            }
        }



        #region System
        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            m_sprite = new SpriteDTO();
            grvModule.DataSource = SpriteBUS.GetDataModule(m_sprite);
            dgvFrames.DataSource = SpriteBUS.GetDataFrame(m_sprite);
            dgvAnimation.DataSource = SpriteBUS.GetDataAnimation(m_sprite);
            dgvAFrames.DataSource = SpriteBUS.GetDataAFrame(m_sprite, 0);
            dgvFModules.DataSource = SpriteBUS.GetDataFModule(m_sprite, 0);

            pnlImageViewer.Invalidate();
            pnlImageMuduleList.Invalidate();
            txtImage.Text = "";
            ReFreshSpriteStore();
        }
        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileSprite.Filter = "XML Sprite Files (*.XML)|*.xml|" +
                "All files (*.*)|*.*";
            if (openFileSprite.ShowDialog() == DialogResult.OK)
            {
                string path = openFileSprite.FileName;
                try
                {
                    m_sprite = SpriteBUS.Load(path);
                    m_sprite.FilePath = path;

                }
                catch
                {
                    MessageBox.Show("File erorr!!!");
                }

                RefreshDataGrid();

                grvModule.ClearSelection();
                dgvFrames.ClearSelection();
                dgvAnimation.ClearSelection();
                dgvAFrames.ClearSelection();
                dgvFModules.ClearSelection();
                StoreSelectModule();
                StoreSelectFrame();
                StoreSelectAnimation();
                StoreSelectAFrame();
                StoreSelectFModule();

                pnlImageViewer.Invalidate();
                pnlImageMuduleList.Invalidate();

                if (m_sprite.ImageInfo.Count != 0)
                {
                    txtImage.Text = m_sprite.ImageInfo[0].Path;
                    pnlTransColor.BackColor = Color.FromArgb(m_sprite.ImageInfo[0].Transp);
                }

                ReFreshSpriteStore();

            }
        }

        void RefreshDataGrid()
        {
            grvModule.DataSource = null;
            dgvFrames.DataSource = null;
            dgvAnimation.DataSource = null;
            dgvAFrames.DataSource = null;
            dgvFModules.DataSource = null;

            grvModule.DataSource = SpriteBUS.GetDataModule(m_sprite);
            dgvFrames.DataSource = SpriteBUS.GetDataFrame(m_sprite);
            dgvAnimation.DataSource = SpriteBUS.GetDataAnimation(m_sprite);
            dgvAFrames.DataSource = SpriteBUS.GetDataAFrame(m_sprite, 0); m_RowIndexAnimation = 0;
            dgvFModules.DataSource = SpriteBUS.GetDataFModule(m_sprite, 0); m_RowIndexFrame = 0;

            grvModule.DataSource = SpriteBUS.GetDataModule(m_sprite);
            grvModule.Columns[0].Width = 30; grvModule.Columns[0].ReadOnly = true;
            //grvModule.Columns[1].Width = 50; grvModule.Columns[1].ReadOnly = true;
            grvModule.Columns[1].Width = 50; grvModule.Columns[1].ReadOnly = true;
            grvModule.Columns[2].Width = 30;
            grvModule.Columns[3].Width = 30;
            grvModule.Columns[4].Width = 30;
            grvModule.Columns[5].Width = 30;
            grvModule.Columns[6].Width = 250;

            dgvFrames.DataSource = SpriteBUS.GetDataFrame(m_sprite);
            dgvFrames.Columns[0].Width = 30; dgvFrames.Columns[0].ReadOnly = true;
            //dgvFrames.Columns[1].Width = 50; dgvFrames.Columns[1].ReadOnly = true;
            dgvFrames.Columns[1].Width = 50; dgvFrames.Columns[1].ReadOnly = true;
            dgvFrames.Columns[2].Width = 50; dgvFrames.Columns[2].ReadOnly = true;
            dgvFrames.Columns[3].Width = 250;

            dgvFModules.DataSource = SpriteBUS.GetDataFModule(m_sprite, 0);
            dgvFModules.Columns[0].Width = 30; dgvFModules.Columns[0].ReadOnly = true;
            //dgvFModules.Columns[1].Width = 50; dgvFModules.Columns[1].ReadOnly = true;
            dgvFModules.Columns[1].Width = 50; //dgvFModules.Columns[2].ReadOnly = true;
            dgvFModules.Columns[2].Width = 30;
            dgvFModules.Columns[3].Width = 30;
            dgvFModules.Columns[4].Width = 80; dgvFModules.Columns[4].ReadOnly = true;

            dgvAnimation.DataSource = SpriteBUS.GetDataAnimation(m_sprite);
            dgvAnimation.Columns[0].Width = 30; dgvAnimation.Columns[0].ReadOnly = true;
            //dgvAnimation.Columns[1].Width = 50; dgvAnimation.Columns[1].ReadOnly = true;
            dgvAnimation.Columns[1].Width = 50; dgvAnimation.Columns[1].ReadOnly = true;
            dgvAnimation.Columns[2].Width = 50; dgvAnimation.Columns[2].ReadOnly = true;
            dgvAnimation.Columns[3].Width = 250;

            dgvAFrames.DataSource = SpriteBUS.GetDataAFrame(m_sprite, 0);
            dgvAFrames.Columns[0].Width = 30; dgvAFrames.Columns[0].ReadOnly = true;
            //dgvAFrames.Columns[1].Width = 50; dgvAFrames.Columns[1].ReadOnly = true;
            dgvAFrames.Columns[1].Width = 50;
            dgvAFrames.Columns[2].Width = 30;
            dgvAFrames.Columns[3].Width = 30;
            dgvAFrames.Columns[4].Width = 30;
            dgvAFrames.Columns[5].Width = 80; dgvAFrames.Columns[5].ReadOnly = true;

        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Close();
        }
        private void DoSave()
        {
            if (string.IsNullOrEmpty(m_sprite.FilePath))
            {
                saveFileSprite.Filter = "XML Sprite Files (*.XML)|*.xml|" +
                "All files (*.*)|*.*";
                if (saveFileSprite.ShowDialog() == DialogResult.OK)
                {
                    m_sprite.FilePath = saveFileSprite.FileName;
                    SpriteBUS.Save(m_sprite, m_sprite.FilePath);
                }
            }
            else
            {
                SpriteBUS.Save(m_sprite, m_sprite.FilePath);
            }
        }
        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DoSave();
        }
        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (saveFileSprite.ShowDialog() == DialogResult.OK)
            {
                m_sprite.FilePath = saveFileSprite.FileName;
                SpriteBUS.Save(m_sprite, m_sprite.FilePath);
            }
        }

        private void exportToSpeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileSprite.Filter = "SPE Sprite Files (*.SPE)|*.spe|" +
                "All files (*.*)|*.*";
            saveFileSprite.FileName = Path.GetFileNameWithoutExtension(m_sprite.FilePath);
            if (saveFileSprite.ShowDialog() == DialogResult.OK)
            {
                ASprite aSprite = new ASprite();
                aSprite.Load(m_sprite);
                aSprite.SaveV1(saveFileSprite.FileName);
            }
        }

        private void sspToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileSprite.Filter = "SSP Short Sprite Files (*.SSP)|*.ssp|" +
                "All files (*.*)|*.*";
            saveFileSprite.FileName = Path.GetFileNameWithoutExtension(m_sprite.FilePath);
            if (saveFileSprite.ShowDialog() == DialogResult.OK)
            {
                ASprite aSprite = new ASprite();
                aSprite.Load(m_sprite);
                aSprite.SaveShortData(saveFileSprite.FileName, m_sprite.ImageInfo[0].Image);

            }
        }

        private void sspWithCacheModuleToolStripMenuItem_Click(object sender, EventArgs e)
        {
            saveFileSprite.Filter = "SSP Short Sprite Files (*.SSP)|*.ssp|" +
               "All files (*.*)|*.*";
            saveFileSprite.FileName = Path.GetFileNameWithoutExtension(m_sprite.FilePath);
            if (saveFileSprite.ShowDialog() == DialogResult.OK)
            {
                ASprite aSprite = new ASprite();
                aSprite.Load(m_sprite);
                aSprite.SaveShortData(saveFileSprite.FileName, m_sprite.ImageInfo[0].Image, true);

            }
        }

        private void bspriteToolStripMenuItem_Click(object sender, EventArgs e)
        {
            openFileSprite.Filter = "Bsprite Sprite Files (*.bsprite)|*.bsprite|" +
                "All files (*.*)|*.*";
            if (openFileSprite.ShowDialog() == DialogResult.OK)
            {
                string path = openFileSprite.FileName;
                try
                {
                    m_sprite = SpriteBUS.ImportBSprite(path);
                    m_sprite.FilePath = path;

                }
                catch
                {
                    MessageBox.Show("File erorr!!!");
                }

                RefreshDataGrid();

                grvModule.ClearSelection();
                dgvFrames.ClearSelection();
                dgvAnimation.ClearSelection();
                dgvAFrames.ClearSelection();
                dgvFModules.ClearSelection();
                StoreSelectModule();
                StoreSelectFrame();
                StoreSelectAnimation();
                StoreSelectAFrame();
                StoreSelectFModule();

                pnlImageViewer.Invalidate();
                pnlImageMuduleList.Invalidate();

                if (m_sprite.ImageInfo.Count != 0)
                {
                    txtImage.Text = m_sprite.ImageInfo[0].Path;
                    pnlTransColor.BackColor = Color.FromArgb(m_sprite.ImageInfo[0].Transp);
                }

                ReFreshSpriteStore();

            }
        }
        protected override void OnClosing(CancelEventArgs e)
        {
            if (MessageBox.Show("Do you want to save!!!", "Exting...", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                DoSave();
            }
            base.OnClosing(e);
        }
        #endregion

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            frmOption frm = new frmOption(m_option);
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                pnlImageViewer.Invalidate();
            }
        }
        const int MAX_SPTIRE_STORE = 20;
        SpriteDTO[] m_HistorySprites;
        ControlState[] m_HistoryControlState;
        int m_iHistorySprites;
        int m_noStore;
        int m_nbUndo;

        void ReFreshSpriteStore()
        {
            m_iHistorySprites = -1;
            m_noStore = 0;
            SpriteStore();
            undoToolStripMenuItem.Enabled = false;
            redoToolStripMenuItem.Enabled = false;
        }

        void StoreControlState(int i)
        {
            m_HistoryControlState[i].ColumnIndexAFrame = m_ColumnIndexAFrame;
            m_HistoryControlState[i].RowIndexAFrame = m_RowIndexAFrame;
            m_HistoryControlState[i].ColumnIndexAnimation = m_ColumnIndexAnimation;
            m_HistoryControlState[i].RowIndexAnimation = m_RowIndexAnimation;
            m_HistoryControlState[i].ColumnIndexFModule = m_ColumnIndexFModule;
            m_HistoryControlState[i].RowIndexFModule = m_RowIndexFModule;
            m_HistoryControlState[i].ColumnIndexFrame = m_ColumnIndexFrame;
            m_HistoryControlState[i].RowIndexFrame = m_RowIndexFrame;
            m_HistoryControlState[i].ColumnIndexModule = m_ColumnIndexModule;
            m_HistoryControlState[i].RowIndexModule = m_RowIndexModule;
        }
        void RestoreControlState(int i)
        {
            m_ColumnIndexAFrame = m_HistoryControlState[i].ColumnIndexAFrame;
            m_RowIndexAFrame = m_HistoryControlState[i].RowIndexAFrame;
            m_ColumnIndexAnimation = m_HistoryControlState[i].ColumnIndexAnimation;
            m_RowIndexAnimation = m_HistoryControlState[i].RowIndexAnimation;
            m_ColumnIndexFModule = m_HistoryControlState[i].ColumnIndexFModule;
            m_RowIndexFModule = m_HistoryControlState[i].RowIndexFModule;
            m_ColumnIndexFrame = m_HistoryControlState[i].ColumnIndexFrame;
            m_RowIndexFrame = m_HistoryControlState[i].RowIndexFrame;
            m_ColumnIndexModule = m_HistoryControlState[i].ColumnIndexModule;
            m_RowIndexModule = m_HistoryControlState[i].RowIndexModule;
        }

        void SpriteStore()
        {
            m_iHistorySprites = (m_iHistorySprites + 1) % MAX_SPTIRE_STORE;
            m_HistorySprites[m_iHistorySprites].Copy(m_sprite);
            StoreControlState(m_iHistorySprites);

            m_nbUndo = 0;

            if (m_noStore < MAX_SPTIRE_STORE)
                m_noStore++;
            if (m_noStore > 1)
            {
                if (undoToolStripMenuItem.Enabled == false)
                    undoToolStripMenuItem.Enabled = true;
            }
        }
        private void undoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (m_nbUndo < MAX_SPTIRE_STORE - 1 && m_noStore > 1)
            {
                m_iHistorySprites = (m_iHistorySprites + MAX_SPTIRE_STORE - 1) % MAX_SPTIRE_STORE;
                m_noStore--;
                m_nbUndo++;
                m_sprite.Copy(m_HistorySprites[m_iHistorySprites]);

                RefreshDataGrid();
                RestoreControlState(m_iHistorySprites);
                ReStoreSelectModule();
                ReStoreSelectFrame();
                ReStoreSelectAnimation();
                ReStoreSelectAFrame();
                ReStoreSelectFModule();

                pnlImageViewer.Invalidate();
                pnlImageMuduleList.Invalidate();
                redoToolStripMenuItem.Enabled = true;
            }
            if (m_noStore <= 1)
            {
                if (undoToolStripMenuItem.Enabled == true)
                    undoToolStripMenuItem.Enabled = false;
            }

        }

        private void redoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (m_nbUndo > 0)
            {
                m_iHistorySprites = (m_iHistorySprites + 1) % MAX_SPTIRE_STORE;
                m_noStore++;
                m_nbUndo--;
                m_sprite.Copy(m_HistorySprites[m_iHistorySprites]);

                RefreshDataGrid();
                RestoreControlState(m_iHistorySprites);
                ReStoreSelectModule();
                ReStoreSelectFrame();
                ReStoreSelectAnimation();
                ReStoreSelectAFrame();
                ReStoreSelectFModule();

                pnlImageViewer.Invalidate();
                pnlImageMuduleList.Invalidate();
            }
            else
            {
                if (redoToolStripMenuItem.Enabled == true)
                    redoToolStripMenuItem.Enabled = false;
            }

            if (m_nbUndo <= 0)
            {
                if (redoToolStripMenuItem.Enabled == true)
                    redoToolStripMenuItem.Enabled = false;
            }
            if (m_noStore > 1)
            {
                if (undoToolStripMenuItem.Enabled == false)
                    undoToolStripMenuItem.Enabled = true;
            }
        }

        private void flipHorizontalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (m_IsDrawBoundRect)
            {
                if (tabTool.SelectedIndex == 1)
                {
                    int index = m_RowIndexFModule;
                    SpriteBUS.FlipFModule(m_sprite, m_RowIndexFrame, index, SpriteDTO.FLIP_Y);
                    pnlImageViewer.Invalidate();
                }
                else if (tabTool.SelectedIndex == 2)
                {
                    int index = m_RowIndexAFrame;
                    SpriteBUS.FlipAFrame(m_sprite, m_RowIndexAnimation, index, SpriteDTO.FLIP_Y);
                    pnlImageViewer.Invalidate();
                }

            }
        }

        private void flipVerticalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (m_IsDrawBoundRect)
            {
                if (tabTool.SelectedIndex == 1)
                {
                    int index = m_RowIndexFModule;
                    SpriteBUS.FlipFModule(m_sprite, m_RowIndexFrame, index, SpriteDTO.FLIP_X);
                    pnlImageViewer.Invalidate();
                }
                else if (tabTool.SelectedIndex == 2)
                {
                    int index = m_RowIndexAFrame;
                    SpriteBUS.FlipAFrame(m_sprite, m_RowIndexAnimation, index, SpriteDTO.FLIP_X);
                    pnlImageViewer.Invalidate();
                }

            }
        }

        private void rotateCWToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (m_IsDrawBoundRect)
            {
                if (tabTool.SelectedIndex == 1)
                {
                    int index = m_RowIndexFModule;
                    SpriteBUS.RotateCWFModule(m_sprite, m_RowIndexFrame, index);
                    pnlImageViewer.Invalidate();
                }
                //else if (tabTool.SelectedIndex == 2)
                //{
                //    int index = m_RowIndexAFrame;
                //    SpriteBUS.FlipAFrame(m_sprite, m_RowIndexAnimation, index, SpriteDTO.ROTATE_90);
                //    pnlImageViewer.Invalidate();
                //}

            }
        }

        private void rotateCCWToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (m_IsDrawBoundRect)
            {
                if (tabTool.SelectedIndex == 1)
                {
                    int index = m_RowIndexFModule;
                    SpriteBUS.RotateCCWFModule(m_sprite, m_RowIndexFrame, index);
                    pnlImageViewer.Invalidate();
                }
                //else if (tabTool.SelectedIndex == 2)
                //{
                //    int index = m_RowIndexAFrame;
                //    SpriteBUS.FlipAFrame(m_sprite, m_RowIndexAnimation, index, SpriteDTO.ROTATE_90);
                //    pnlImageViewer.Invalidate();
                //}

            }
        }

        private void topToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tabTool.SelectedIndex == 1)
            {
                for (int i = 0; i < m_sprite.Frames.Count; i++)
                {
                    SpriteBUS.AlignTop(m_sprite, i, 0);
                }
                //SpriteBUS.AlignTop(m_sprite, m_RowIndexFrame, m_RowIndexFModule);

                pnlImageViewer.Invalidate();
            }
            else if (tabTool.SelectedIndex == 2)
            {

            }

        }

        private void leftToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }














    }
}
